package com.ljt.yupictureddd.interfaces.controller;

import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.ljt.yupictureddd.infrastracture.annotation.AuthCheck;
import com.ljt.yupictureddd.infrastracture.common.BaseResponse;
import com.ljt.yupictureddd.infrastracture.common.DeleteRequest;
import com.ljt.yupictureddd.infrastracture.common.ResultUtils;
import com.ljt.yupictureddd.domain.user.constant.UserConstant;
import com.ljt.yupictureddd.infrastracture.exception.ErrorCode;
import com.ljt.yupictureddd.infrastracture.exception.ThrowUtils;
import com.ljt.yupictureddd.shared.manager.auth.SpaceUserAuthManager;
import com.ljt.yupictureddd.interfaces.assembler.SpaceAssembler;
import com.ljt.yupictureddd.interfaces.dto.space.SpaceLevel;
import com.ljt.yupictureddd.interfaces.dto.space.SpaceAddRequest;
import com.ljt.yupictureddd.interfaces.dto.space.SpaceEditRequest;
import com.ljt.yupictureddd.interfaces.dto.space.SpaceQueryRequest;
import com.ljt.yupictureddd.interfaces.dto.space.SpaceUpdateRequest;
import com.ljt.yupictureddd.domain.space.entity.Space;
import com.ljt.yupictureddd.domain.user.entity.User;
import com.ljt.yupictureddd.domain.space.valueobject.SpaceLevelEnums;
import com.ljt.yupictureddd.application.service.SpaceApplicationService;
import com.ljt.yupictureddd.application.service.UserApplicationService;
import com.ljt.yupictureddd.interfaces.vo.space.SpaceVO;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/space")
public class SpaceController {
    @Resource
    UserApplicationService userApplicationService;

    @Resource
    SpaceApplicationService spaceApplicationService;
    @Resource
    private SpaceUserAuthManager spaceUserAuthManager;

    /**
     * 创建空间
     */
    @PostMapping("/add")
    public BaseResponse addSpace(@RequestBody SpaceAddRequest spaceAddRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(Objects.isNull(spaceAddRequest), ErrorCode.PARAMS_ERROR,"参数为空");
        User loginUser = userApplicationService.getLoginUser(request);
        long spaceId = spaceApplicationService.createSpace(spaceAddRequest, loginUser);
        return ResultUtils.success(spaceId);
    }


    /**
     * 删除图片
     */
    @PostMapping("/delete")
    public BaseResponse deleteSpace(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
        Long id = deleteRequest.getId();
        ThrowUtils.throwIf(ObjUtil.isNull(id), ErrorCode.PARAMS_ERROR);

//        校验数据库有没有这条数据
        Space oldSpace = spaceApplicationService.getById(id);
        ThrowUtils.throwIf(ObjUtil.isNull(oldSpace), ErrorCode.NOT_FOUND_ERROR);
//        必须是管理员 或者是本人才可以删除
        User loginUser = userApplicationService.getLoginUser(request);
        Long loginUserId = loginUser.getId();
        spaceApplicationService.checkSpaceAuth(loginUser,oldSpace);
        // ThrowUtils.throwIf(!(Objects.equals(loginUserId, oldSpace.getUserId())) || !userService.isAdmin(loginUser), ErrorCode.NO_AUTH_ERROR);
//        操作数据库
        boolean result = spaceApplicationService.removeById(id);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(true);
    }

    /**
     * 只有管理员可用， 更新图片
     */
    @PostMapping("/update")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse updateSpace(@RequestBody SpaceUpdateRequest spaceUpdateRequest, HttpServletRequest request) {
//        1.校验参数
        ThrowUtils.throwIf(ObjUtil.isNull(spaceUpdateRequest), ErrorCode.PARAMS_ERROR, "参数为空");
//        封装po后还是要校验
        Space space = SpaceAssembler.toSpaceEntity(spaceUpdateRequest);
        space.validSpace(false);
//        更新判断存在
        Space oldSpace = spaceApplicationService.getById(space.getId());
        ThrowUtils.throwIf(ObjUtil.isNull(oldSpace), ErrorCode.NOT_FOUND_ERROR);
//        2.校验身份是不是管理员 =》 注解做了

        //        补充空间参数
        space.fillSpaceBySpaceLevel();
//        4.操作数据库
        boolean save = spaceApplicationService.updateById(space);
        ThrowUtils.throwIf(!save, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(true);
    }


    /**
     * 仅管理员可用的，根据id获取图片
     */
    @GetMapping("/get")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse getSpaceById(long id, HttpServletRequest request) {
//        校验参数（无）、转换为po再校验
        ThrowUtils.throwIf(id < 0, ErrorCode.PARAMS_ERROR);
//        校验权限 =》 注解做了
//        校验数据库存在？
        Space oldSpace = spaceApplicationService.getById(id);
        ThrowUtils.throwIf(ObjUtil.isNull(oldSpace), ErrorCode.NOT_FOUND_ERROR);
        return ResultUtils.success(oldSpace);
    }

    /**
     * 根据id获取图片 （要脱敏）
     *
     * @param id
     * @param request
     * @return
     */
    @GetMapping("/get/vo")
    public BaseResponse getSpaceVO(Long id, HttpServletRequest request) {
//        校验参数（无）、转换为po再校验
        ThrowUtils.throwIf(ObjUtil.isNull(id) || id < 0, ErrorCode.PARAMS_ERROR);
//        校验权限 = > 无需
//        校验数据库存在？
        Space oldSpace = spaceApplicationService.getById(id);
        ThrowUtils.throwIf(ObjUtil.isNull(oldSpace), ErrorCode.NOT_FOUND_ERROR);

//        1.进行数据脱敏
        SpaceVO spaceVO = spaceApplicationService.getSpaceVO(oldSpace, request);
        User loginUser = userApplicationService.getLoginUser(request);
        List<String> permissionList = spaceUserAuthManager.getPermissionList(oldSpace, loginUser);
        spaceVO.setPermissionList(permissionList);
        return ResultUtils.success(spaceVO);
    }

    /**
     * 分页获取列表(管理员才可以用)
     */
    @PostMapping("/list/page")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse listSpaceByPage(@RequestBody SpaceQueryRequest spaceQueryRequest) {
//        校验参数（无）、转换为po再校验
        ThrowUtils.throwIf(ObjUtil.isNull(spaceQueryRequest), ErrorCode.PARAMS_ERROR, "参数为空");
//        校验权限 = > 无需
//        校验数据库存在？ => 无需
        int current = spaceQueryRequest.getCurrent();
        int pageSize = spaceQueryRequest.getPageSize();
        Page<Space> spacePage = spaceApplicationService.page(new Page<>(current, pageSize), spaceApplicationService.getQueryWrapper(spaceQueryRequest));
        return ResultUtils.success(spacePage);
    }

    /**
     * 分页获取列表(封装类,脱敏类)
     */
    @PostMapping("/list/page/vo")
    public BaseResponse listSpaceVOByPage(@RequestBody SpaceQueryRequest spaceQueryRequest, HttpServletRequest request) {
//        校验参数（无）、转换为po再校验
        ThrowUtils.throwIf(ObjUtil.isNull(spaceQueryRequest), ErrorCode.PARAMS_ERROR, "参数为空");
//        校验权限 = > 无需
//        校验数据库存在？ => 无需
        int current = spaceQueryRequest.getCurrent();
        int pageSize = spaceQueryRequest.getPageSize();
        Page<Space> spacePage = spaceApplicationService.page(new Page<>(current, pageSize), spaceApplicationService.getQueryWrapper(spaceQueryRequest));
        Page<SpaceVO> spaceVOList = spaceApplicationService.getSpaceVOList(spacePage, request);
        return ResultUtils.success(spaceVOList);
    }

    /**
     * 编辑图片(给用户使用的)
     */
    @PostMapping("edit")
    public BaseResponse editSpace(@RequestBody SpaceEditRequest spaceEditRequest, HttpServletRequest request) {
//        校验参数（无）、转换为po再校验
        ThrowUtils.throwIf(ObjUtil.isNull(spaceEditRequest), ErrorCode.PARAMS_ERROR, "参数为空");
        Space space = SpaceAssembler.toSpaceEntity(spaceEditRequest);
        space.validSpace(false);
//        校验数据库存在？ =>
        Long id = spaceEditRequest.getId();
        Space oldSpace = spaceApplicationService.getById(id);
        ThrowUtils.throwIf(ObjUtil.isNull(oldSpace), ErrorCode.NOT_FOUND_ERROR);
//        校验权限 = > 只有本人,或者管理员才行
        Long spaceUserId = oldSpace.getUserId();
        User loginUser = userApplicationService.getLoginUser(request);
        spaceApplicationService.checkSpaceAuth(loginUser,space);
        // ThrowUtils.throwIf(!ObjUtil.equals(loginUser.getId(), spaceUserId) || !userService.isAdmin(loginUser), ErrorCode.NO_AUTH_ERROR);
//        补充审核参数
        space.fillSpaceBySpaceLevel();
//        0.操作数据库前,检查参数
        space.setEditTime(new Date());
//        1.操作数据库
        boolean update = spaceApplicationService.updateById(space);
        ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(true);
    }

    /**
     * 获取空间级别列表,便于前端展示
     * @return
     */
    @GetMapping("/list/level")
    public BaseResponse listSpaceLevel(){
        List<SpaceLevel> spaceLevelList = Arrays.stream(SpaceLevelEnums.values())
                .map(spaceLevelEnum -> new SpaceLevel(spaceLevelEnum.getText(),
                        spaceLevelEnum.getValue(),
                        spaceLevelEnum.getMaxSize(),
                        spaceLevelEnum.getMaxCount()))
                .collect(Collectors.toList());
        return ResultUtils.success(spaceLevelList);
    }
}
